<?php

/**
 * Maikuro Framework
 *
 * LICENSE:
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * The license is bundled with this package in the file LICENSE.txt.
 * You may also obtain a copy of the License at this URL:
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @copyright  Copyright (c) 2010, Jonathan Hedrén
 * @author     Jonathan Hedrén <jonathan.hedren@gmail.com>
 * @license    http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

/**
 * @see IDbHandler
 */
require_once 'IDbHandler.php';

/**
 * Database helper class.
 */
class DbHelper
{
    /**
     * The database handler (must implement the IDbHandler interface).
     *
     * @var IDbHandler
     */
    protected static $dbHandler;

    /**
     * Deletes rows from the database.
     *
     * @param string $from
     * @param string $where
     * @return DbResult
     */
    public static function delete($from, $where = null, array $values = array()) {
        $sql = 'DELETE FROM ' . $from;
        if ($where !== null) {
            $sql .= ' WHERE ' . $where;
        }
        return self::query($sql, $values);;
    }

    /**
     * Inserts a row into the database.
     *
     * @param string $into
     * @param array $columnsAndValues
     * @return DbResult
     */
    public static function insert($into, array $columnsAndValues)
    {
        $columns = array_keys($columnsAndValues);
        $values = array_values($columnsAndValues);
        $sql = 'INSERT INTO ' . $into . ' (' . implode(', ', $columns) . ')'
             . ' VALUES ' . '(' . trim(str_repeat('?, ', count($values)), ', ') . ')';
        return self::query($sql, $values);;
    }

    /**
     * Returns the database handler.
     *
     * @return IDbHandler
     */
    public static function getDbHandler()
    {
        return self::$dbHandler;
    }

    /**
     * Queries the database handler.
     *
     * @param string $sql
     * @param array $values
     * @return DbResult
     */
    public static function query($sql, $values = array())
    {
        if (self::$dbHandler === null) {
            throw new Exception('No database handler set.');
        }
        
        if (!is_array($values)) {
            $values = array($values);
        }
        
        return self::$dbHandler->query($sql, $values);
    }

    /**
     * Selects rows from the database.
     *
     * @param string $columns
     * @param string $from
     * @param string $where
     * @param string|array $values
     * @param string $extras
     * @return DbResult
     */
    public static function select($columns, $from, $where = null, $values = array(), $extras = null)
    {
        $sql = 'SELECT ' . $columns . ' FROM ' . $from;
        if ($where !== null) {
            $sql .= ' WHERE ' . $where;
        }
        if ($extras !== null) {
            $sql .= ' ' . $extras;
        }
        if (!is_array($values)) {
            $values = array($values);
        }
        return self::query($sql, $values);
    }

    /**
     * Sets the database handler.
     *
     * @param IDbHandler $dbHandler
     * @return void
     */
    public static function setDbHandler(IDbHandler $dbHandler)
    {
        self::$dbHandler = $dbHandler;
    }

    /**
     * Updates rows in the database.
     *
     * @param string $table
     * @param array $fieldsAndValues
     * @param string $where
     * @param mixed $whereVal
     * @return DbResult
     */
    public static function update($table, $fieldsAndValues, $where = null, $whereVal = null)
    {
        $fields = '';
        foreach ($fieldsAndValues as $key => $value) {
                $fields .= $key . ' = ?, ';
        }
        $values = array_values($fieldsAndValues);
        $sql = 'UPDATE ' . $table . ' SET ' . trim($fields, ' ,');

        if ($where !== null && $whereVal !== null) {
            $sql .= ' WHERE ' . $where . ' ?';
            $values[] = $whereVal;
        }

        return self::query($sql, $values);;
    }
}